package com.iguo.news.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iguo.news.common.NewRecommend;
import com.iguo.news.entity.New;
import com.iguo.news.entity.NewScore;
import com.iguo.news.entity.NewWithScore;
import com.iguo.news.mapper.NewMapper;
import com.iguo.news.mapper.NewScoreMapper;
import com.iguo.news.service.NewScoreService;
import com.iguo.news.util.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class NewScoreServiceImpl extends ServiceImpl<NewScoreMapper, NewScore> implements NewScoreService {

  @Autowired
  NewMapper newMapper;

  @Autowired
  NewScoreMapper newScoreMapper;

  @Override
  public List<New> recommend(String userId) {
    System.out.println(userId);
    List<New> newList = new ArrayList<>();
    try (Connection conn = DriverManager.getConnection(NewRecommend.DB_URL, NewRecommend.USER, NewRecommend.PASS)) {
      // 加载用户评分数据
      Map<String, Map<String, Double>> userRatings = NewRecommend.loadRatingsFromDB1(conn);

/*
      for (Map.Entry<String, Map<String, Double>> userEntry : userRatings.entrySet()) {
        String user = userEntry.getKey();
        Map<String, Double> itemRatings = userEntry.getValue();
        System.out.println("用户: " + user);
        System.out.println(itemRatings);
      }*/

      // 找到与目标用户最相似的三个用户
      List<String> similarUsers = NewRecommend.findTopThreeSimilarUsers(userId, userRatings);
      System.err.println("与用户 " + userId + " 最相似的三个用户为：" + similarUsers);

      // 基于相似用户推荐新闻
      List<Map.Entry<String, Integer>> recommendedNews = NewRecommend.recommendNewsBasedOnSimilarUsers(userRatings, similarUsers, userId);

      // 根据推荐的新闻 ID 查询新闻信息
      for (Map.Entry<String, Integer> entry : recommendedNews) {
        String newId = entry.getKey();
        LambdaQueryWrapper<New> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(New::getId, newId);
        New news = newMapper.selectOne(queryWrapper);
        if (news != null) {
          newList.add(news);
        }
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }

    return newList;
  }

  @Override
  public boolean updateScore(NewScore newScore) {
    // 1. 参数校验
    if (newScore == null) {
      throw new IllegalArgumentException("评分对象不能为null");
    }

    // 2. 设置更新时间（精确到秒）
    newScore.setTime(LocalDateTime.now());
    System.out.println("设置更新时间: " + newScore.getTime());

    // 3. 构建查询条件
    LambdaQueryWrapper<NewScore> queryWrapper = new LambdaQueryWrapper<>();
    if (newScore.getId() != null) {
      queryWrapper.eq(NewScore::getId, newScore.getId());
    } else {
      // 双重校验确保必要参数存在
      if (newScore.getUserId() == null || newScore.getNewId() == null) {
        throw new IllegalArgumentException("用户ID和新闻ID不能同时为null");
      }
      queryWrapper.eq(NewScore::getUserId, newScore.getUserId())
              .eq(NewScore::getNewId, newScore.getNewId());
    }

    // 4. 查询现有记录
    NewScore existingScore = newScoreMapper.selectOne(queryWrapper);

    try {
      if (existingScore != null) {
        // 5. 更新操作（只更新非null字段）
        LambdaQueryWrapper<NewScore> updateWrapper = new LambdaQueryWrapper<>();
        updateWrapper.eq(NewScore::getId, existingScore.getId()); // 始终使用主键更新

        // 创建更新对象，避免覆盖其他字段
        NewScore updateEntity = new NewScore();
        updateEntity.setId(existingScore.getId());
        updateEntity.setScore(newScore.getScore());
        updateEntity.setTime(newScore.getTime());

        return newScoreMapper.update(updateEntity, updateWrapper) > 0;
      } else {
        // 6. 新增操作
        if (newScore.getId() == null) {
          newScore.setId(UUIDUtil.generateShortNumericId());
        }
        return newScoreMapper.insert(newScore) > 0;
      }
    } catch (Exception e) {
      System.err.println("评分更新失败: " + e.getMessage());
      e.printStackTrace();
      return false;
    }
  }

  public List<NewWithScore> getNewWithScoreByUserId(Integer userId) {
    return newScoreMapper.getNewWithScoreByUserId(userId);
  }

  public boolean deleteById(Integer id) {
    newScoreMapper.deleteById(id);
    return true;
  }
}